#pragma once

#include <cassert>
#include <cstdint>
#include <memory>
#include <unordered_set>

#include "evt_loop.h"
#include "timer.h"

namespace qio {

class TimeoutHandle : public std::enable_shared_from_this<TimeoutHandle> {
 public:
  // 暂停定时器
  virtual void Pause() QIO_NOEXCEPT = 0;

  // 重置定时器
  virtual void Reset() QIO_NOEXCEPT = 0;

  // 获取设定的超时时间
  virtual TimeoutMs GetTimeoutMs() const QIO_NOEXCEPT = 0;

  // 获取共享的实例
  virtual std::shared_ptr<TimeoutHandle> GetSharedHandle() QIO_NOEXCEPT = 0;

  //
  virtual ~TimeoutHandle() QIO_NOEXCEPT = 0;
};

using SharedTimeoutHandle = std::shared_ptr<TimeoutHandle>;

class TimeWheel final {
 public:
  using Entry = std::shared_ptr<TimeoutHandle>;
  using Element = std::unordered_set<Entry>;
  using WheelQueue = std::list<Element>;
  using BucketId = int;

  explicit TimeWheel(EventLoop *loop) QIO_NOEXCEPT;

  ~TimeWheel() QIO_NOEXCEPT;

  void AddEntry(const Entry &entry) QIO_NOEXCEPT;

  TimeoutMs GetTimeoutMs() const QIO_NOEXCEPT { return timeout_ms_; }

  bool IsWorking() QIO_NOEXCEPT { return timer_ != nullptr; }

  const Element &GetCurrentElement() const QIO_NOEXCEPT {
    return bucket_queue_.back();
  }

  // 设定 timeout 并且启动 timeWheel
  // timeout = 0 代表永不超时
  void StartTimeout(TimeoutMs timeout) QIO_NOEXCEPT;

 private:
  EventLoop *loop_;
  TimeoutMs timeout_ms_;
  SharedTimer timer_;
  WheelQueue bucket_queue_;
};

}  // namespace qio